%{
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>

#define YYDEBUG 1

extern void yyerror(const char *);
extern yylex(), yyparse();
extern void _VSetDataToScan(NSData *someData);
extern void _VRegisterTypeName(const char *aTypeName);
extern BOOL _VIsKnownTypeName(const char *aTypeName);
extern char _VCurrentIdentifier[512];

%}

%token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
%token PTR_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP TYPE_NAME

%token CHAR INT VOID
%token ENUM

%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR CONTINUE BREAK RETURN

%token INTERFACE IMPLEMENTATION END

%start translation_unit

%%
/**1. Expression */
//основные выражения
primary_expression
        : IDENTIFIER
        | CONSTANT
        | STRING_LITERAL
        | '(' expression ')'
        ;
//постфиксные выражения
postfix_expression
        : primary_expression
        | postfix_expression '[' expression ']'
        | postfix_expression '(' ')'
        | postfix_expression '(' argument_expression_list ')'
        | postfix_expression '.' IDENTIFIER
        | postfix_expression PTR_OP IDENTIFIER
        ;
//список аргументов выражения
argument_expression_list
        : assignment_expression
        | argument_expression_list ',' assignment_expression
        ;
//унарные выражения
unary_expression
        : postfix_expression
        | unary_operator 
        | SIZEOF unary_expression
        | SIZEOF '(' type_name ')'
        ;
//унарный оператор
unary_operator
        : '+'
        | '-'
        | '!'
        ;
//умножение деление остаток
multiplicative_expression
        : unary_expression
        | multiplicative_expression '*' unary_expression
        | multiplicative_expression '/' unary_expression
        | multiplicative_expression '%' unary_expression
        ;
//аддитивные выражения
additive_expression
        : multiplicative_expression
        | additive_expression '+' multiplicative_expression
        | additive_expression '-' multiplicative_expression
        ;

//выражения отношений
relational_expression
        : additive_expression
        | relational_expression '<' additive_expression
        | relational_expression '>' additive_expression
        | relational_expression LE_OP additive_expression
        | relational_expression GE_OP additive_expression
        ;
//выражение равенства
equality_expression
        : relational_expression
        | equality_expression EQ_OP relational_expression
        | equality_expression NE_OP relational_expression
        ;
		
//И
logical_and_expression
        : equality_expression
        | logical_and_expression AND_OP equality_expression
        ;
//ИЛИ 
logical_or_expression
        : logical_and_expression
        | logical_or_expression OR_OP logical_and_expression
        ;
		
//выражение присваивания
assignment_expression
        : logical_or_expression
        | unary_expression assignment_operator assignment_expression
        ;
		
//выражения присваивания
assignment_operator
        : '='
        ;
//выражение
expression
        : assignment_expression
        | expression ',' assignment_expression
        ;
//константное выражение
constant_expression
        : logical_or_expression
        ;
/**Declaration*/
//описание
declaration
        : declaration_specifiers ';'
        | type_declaration ';'
        | declaration_specifiers init_declarator_list ';'
        ;
//спецификаторы описания
declaration_specifiers
        : type_specifier
        | type_specifier declaration_specifiers
        ;

/**Declarator*/
//список инициализаций 
init_declarator_list
        : init_declarator
        | init_declarator_list ',' init_declarator
        ;
//описание инициализации
init_declarator
        : declarator
        | declarator '=' initializer
        ;

//описание типа
type_declarator
        : pointer type_direct_declarator
        | type_direct_declarator
        ;
//???
type_direct_declarator
        : IDENTIFIER
        {
			_VRegisterTypeName(_VCurrentIdentifier);
		}
        | '(' type_declarator ')'
        | type_direct_declarator '[' constant_expression ']'
        | type_direct_declarator '[' ']'
        | type_direct_declarator '(' parameter_list ')'
        | type_direct_declarator '(' identifier_list ')'
        | type_direct_declarator '(' ')'
        ;
//???
type_declaration
        : declaration_specifiers type_declarator
		;
//стандартные типы
type_specifier
        : VOID
        | CHAR
        | INT
        | enum_specifier
        | TYPE_NAME
        ;

//??
specifier_qualifier_list
        : type_specifier specifier_qualifier_list
        | type_specifier
        ;

//описание enum
enum_specifier
        : ENUM '{' enumerator_list '}'
        | ENUM IDENTIFIER '{' enumerator_list '}'
		{
			_VRegisterTypeName(_VCurrentIdentifier);
		}
		| ENUM IDENTIFIER
		{
			_VRegisterTypeName(_VCurrentIdentifier);
		}
        ;
//список значений в enum
enumerator_list
        : enumerator
        | enumerator_list ',' enumerator
        ;
//значение пересисления
enumerator
        : IDENTIFIER
        | IDENTIFIER '=' constant_expression
        ;

//описатель
declarator
        : pointer direct_declarator
        | direct_declarator
        ;
//?
direct_declarator
        : IDENTIFIER
        | '(' declarator ')'
        | direct_declarator '[' constant_expression ']'
        | direct_declarator '[' ']'
        | direct_declarator '(' parameter_list ')'
        | direct_declarator '(' identifier_list ')'
        | direct_declarator '(' ')'
        ;
//указатели
pointer
        : '*'
        | '*' pointer
        ;

//список параметров
parameter_list
        : parameter_declaration
        | parameter_list ',' parameter_declaration
        ;
//объявление параметра
parameter_declaration
        : declaration_specifiers declarator
        | declaration_specifiers abstract_declarator
        | declaration_specifiers
        ;
//список идентификаторов
identifier_list
        : IDENTIFIER
        | identifier_list ',' IDENTIFIER
        ;
//имя типа?
type_name
        : specifier_qualifier_list
        | specifier_qualifier_list abstract_declarator
        ;
//?
abstract_declarator
        : pointer
        | direct_abstract_declarator
        | pointer direct_abstract_declarator
        ;
//..
direct_abstract_declarator
        : '(' abstract_declarator ')'
        | '[' ']'
        | '[' constant_expression ']'
        | direct_abstract_declarator '[' ']'
        | direct_abstract_declarator '[' constant_expression ']'
        | '(' ')'
        | '(' parameter_list ')'
        | direct_abstract_declarator '(' ')'
        | direct_abstract_declarator '(' parameter_list ')'
        ;
//инциализатор
initializer
        : assignment_expression
        | '{' initializer_list '}'
        | '{' initializer_list ',' '}'
        ;
//список инициализаторов
initializer_list
        : initializer
        | initializer_list ',' initializer
        ;
//выражение
statement
        : labeled_statement
        | compound_statement
        | expression_statement
        | selection_statement
        | iteration_statement
        | jump_statement
        ;
//
labeled_statement
        : CASE constant_expression ':' statement
        | DEFAULT ':' statement
        ;
//
compound_statement
        : '{' '}'
        | '{' statement_list '}'
        | '{' declaration_list '}'
        | '{' declaration_list statement_list '}'
        ;
//список объявлеий
declaration_list
        : declaration
        | declaration_list declaration
        ;
//список операторов
statement_list
        : statement
        | statement_list statement
        ;
//выражение
expression_statement
        : ';'
        | expression ';'
        ;
//операторы выбора
selection_statement
        : IF '(' expression ')' statement
        | IF '(' expression ')' statement ELSE statement
        | SWITCH '(' expression ')' statement
        ;
//оператора повторения
iteration_statement
        : WHILE '(' expression ')' statement
        | DO statement WHILE '(' expression ')' ';'
        | FOR '(' expression_statement expression_statement ')' statement
        | FOR '(' expression_statement expression_statement expression ')' statement
        ;
//операторы перехода
jump_statement
        : CONTINUE ';'
        | BREAK ';'
        | RETURN ';'
        | RETURN expression ';'
        ;
//?
translation_unit
        : external_declaration
        | translation_unit external_declaration
        ;
//внешние объявления?
external_declaration
        : function_definition
        | declaration
		| class_interface
		| class_implementation
        ;
//определение функции
function_definition
        : declaration_specifiers declarator declaration_list compound_statement
        | declaration_specifiers declarator compound_statement
        | declarator declaration_list compound_statement
        | declarator compound_statement
        ;
//описание класса
class_interface
		: INTERFACE class_name instance_variables interface_declaration_list END
		| INTERFACE class_name ':' superclass_name instance_variables interface_declaration_list END
		;

class_implementation
		: IMPLEMENTATION class_name implementation_definition_list END
		;

class_name
		: IDENTIFIER
		;

superclass_name
		: IDENTIFIER
		;

instance_variables
		: '{' struct_declaration_list '}'
		| '{' '}'
		;
		
struct_declaration_list
        : struct_declaration
        | struct_declaration_list struct_declaration
        ;

struct_declaration
        : specifier_qualifier_list struct_declarator_list ';'
        ;

struct_declarator_list
        : declarator
        | struct_declarator_list ',' declarator
        ;

interface_declaration_list
		: method_declaration
		| interface_declaration_list method_declaration
		;

method_declaration
		: class_method_declaration
		| instance_method_declaration
		;

class_method_declaration
		: '+' method_selector ';'
		| '+' method_type method_selector ';'
		;

instance_method_declaration
		: '-' method_selector ';'
		| '-' method_type method_selector ';'
		;

implementation_definition_list
		: function_definition
		| declaration
		| method_definition
		| implementation_definition_list function_definition
		| implementation_definition_list declaration
		| implementation_definition_list method_definition
		;

method_definition
		: class_method_definition
		| instance_method_definition
		;

class_method_definition
		: '+' method_selector compound_statement
		| '+' method_type method_selector compound_statement
		;

instance_method_definition
		: '-' method_selector compound_statement
		| '-' method_type method_selector compound_statement
		;

method_selector
		: unary_selector
		| keyword_selector
		;

unary_selector
		: selector
		;

keyword_selector
		: keyword_declarator
		| keyword_selector keyword_declarator
		;

keyword_declarator
		: ':' IDENTIFIER
		| ':' method_type IDENTIFIER
		| selector ':' IDENTIFIER
		| selector ':' method_type IDENTIFIER
		;

selector
		: IDENTIFIER
		;

method_type
		: '(' type_name ')'
		;

%%
